

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 
 * @author Dagny Jackson
 * Validate class allows us to call many static methods to test for universal
 * requirements without having to work them into our individual forms.
 * All methods and functions created/edited by Dagny Jackson, unless 
 * otherwise specified by comments near/within the coding itself.
 *
 */
public class Validate 
{
	/*
	 * This validates any generic text string so there aren't any
	 * semicolons contained within it, or that there aren't two dashes in a row (--)
	 */
	public static boolean genericText(String toValidate)
	{

		for (int s = 0; s < toValidate.length(); s++)
		{
			char test = toValidate.charAt(s);
			if (test == ';')
			{
				return  false;
			}
		}
		
		for (int d = 0; d< (toValidate.length() - 1); d++)
		{
			String duo = Character.toString(toValidate.charAt(d)) + Character.toString(toValidate.charAt(d+1));
			//System.out.println("Dash duo to check: " + duo);
			if (duo.equals("--"))
			{
				return  false;
			}
		}
	
		return true;
	}
	
	/*
	 * This validates any generic number string to validate it is a number.
	 * method tested between long limitations:
	 * -9,223,372,036,854,775,808 through 9,223,372,036,854,775,807 inclusive
	 * passed all numbers. rejected all non numbers.
	 */
	public static boolean genericLongInteger(String toValidate)
	{
		boolean result = true;
		
		try
		{
			long num = Long.parseLong(toValidate);
			//System.out.println("Integer parsing number result: " + num);
		}
		catch (NumberFormatException nfe)
		{
			nfe.printStackTrace();
			result = false;
		}

		return result;
	}
	
	/*
	 * This validates any generic number string to validate it is a number.
	 */
	public static boolean genericDouble(String toValidate)
	{
		boolean result = true;
		
		try
		{
			double num = Double.parseDouble(toValidate);
			//System.out.println("Integer parsing number result: " + num);
		}
		catch (NumberFormatException nfe)
		{
			nfe.printStackTrace();
			result = false;
		}

		return result;
	}
	
	/*
	 * This validates any string as being non-negative.
	 */
	public static boolean isNotNegative(String toValidate)
	{
		boolean result = true;
		
		char test = toValidate.charAt(0);
		if (test == '-')
		{
			result = false;
		}
		
		return result;
	}

	/*
	 * This validates any fax or phone number
	 * It will determine if the string is a long, and then if it's not negative
	 * and then if it's exactly 10 digits long
	 */
	public static boolean isValidPhoneFax(String toValidate)
	{
		boolean result = true;
		
		if (!genericLongInteger(toValidate))
		{
			result = false;
		}
		if (!isNotNegative(toValidate))
		{
			result = false;
		}
		if (toValidate.length()!=10)
		{
			result = false;
		}
		
		return result;
	}
	
	/*
	 * This validates if a text string is a valid email based on regular expression
	 */
	public static boolean isValidEmail(String toValidate)
	{
		boolean result = false;
		
		String regExpr = "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
		Pattern pattern = Pattern.compile(regExpr);
		Matcher matcher = null;
		matcher = pattern.matcher(toValidate);
		
		if (matcher.matches())
		{
			result = true;
		}
		
		return result;
	}
	
	/*
	 * This validates if a text string is a valid 2 character state or
	 * province code based on regular expressions
	 * WARNING: If the person passes through lower case (like 'ab' instead of 'AB')
	 * this will flag it as FALSE! So to avoid that, you might want to call this method,
	 * and then apply a 'toUppercase()' string function.
	 * Example: Validate.isISOCode(text.toUpperCase())
	 * 
	 * Remember if you're doing this, that you need to then pass 
	 * it to the database with the uppercase function as well.
	 */
	public static boolean isValidISOCode(String toValidate)
	{
		boolean result = false;
		
		String regExpr = "^(?:A[BKLRZ]|BC|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ABDEINOST]|N[BCDEHJLMSTUVY]|O[HKRN]|P[AE]|QC|RI|S[CDK]|T[NX]|UT|V[AT]|W[AIVY]|YT)*$";
		Pattern pattern = Pattern.compile(regExpr);
		Matcher matcher = null;
		matcher = pattern.matcher(toValidate);
		
		if (matcher.matches())
		{
			result = true;
		}
		
		return result;
	}

	
	/*
	 * This validates if a text string is a valid US Zip Code
	 * or Canadian Postal Code
	 * Like the ISOCode, it won't approve lowercase letters, so if 
	 * you're willing to pass them through to the database that way,
	 * test the uppercase version first.
	 * Remember if you're doing this, that you need to then pass 
	 * it to the database with the uppercase function as well.
	 */
	public static boolean isValidPostalZip(String toValidate)
	{
		boolean result = false;
		
		String regExpr = "^([ABCEGHJKLMNPRSTVXY][0-9][A-Z] [0-9][A-Z][0-9])*$";
		Pattern pattern = Pattern.compile(regExpr);
		Matcher matcher = null;
		matcher = pattern.matcher(toValidate);
		
		if (matcher.matches())
		{
			result = true;
		}
		
		String regExpr2 = "^([0-9]{5}(?:-[0-9]{4})?)*$";
		Pattern pattern2 = Pattern.compile(regExpr2);
		matcher = pattern2.matcher(toValidate);
		
		if (matcher.matches())
		{
			result = true;
		}
		
		return result;
	}
	
	/*
	 * This validates whether the first date is earlier than the second date.
	 */
	public static boolean isFirstDateEarlierThanSecond(Date first, Date second)
	{
		boolean result = false;
		
		int difference = first.compareTo(second);
		
		if (difference < 0)
		{
			//a negative result means the first date is earlier than the second
			result = true;
		}
		
		return result;
	}

	
}
